<template>
  <div class="container" @click.stop="showLanguageHandel">
    <div class="page_content container-tt">
      <header class="flex_between">
        <div class="headLogo">
          <div class="flex_ shou" @click="goToApp('video')">
            <img
              src="/static/logo.svg"
              class="img"
              alt="logo"
              width="34"
              height="34"
            />
            <span class="projectName">SavingTik</span>
          </div>
        </div>
        <div class="headTabs flex_">
          <!-- <div class="tItem shou" @click="goToApp('video')">
                {{ currentObj.TikTokDownloader }}
              </div> -->
          <div class="tItem shou" @click="goToApp('mp3')">
            Download TikTok MP3
          </div>
          <div class="tItem shou" @click="goToApp('story')">
            Download TikTok Story
          </div>
          <language
            ref="languageRef"
            :pageType="true"
            :colorFFF="true"
          ></language>
        </div>
        <div class="drawer" @click="showAppRightHandel">
          <img src="/static/menu.png" class="img" alt="" />
        </div>
      </header>
    </div>
    <div class="blog-content">
      <div class="background">
        <div class="content flex_ccenter">
          <div class="cateImg">
            <img :src="articleObj.icon" class="img" :alt="articleObj.type" />
          </div>
          <h1 class="alt-title">
            {{ articleObj.articleTitle }}
          </h1>
          <div class="uname flex_">
            by
            <nuxt-link :to="`/blog/author${articleObj.authorUrl}`">
              <div class="name" @click.stop="StorageAuthorId">
                {{ articleObj.author }}
              </div>
            </nuxt-link>
          </div>
          <div class="info-box flex_">
            <div class="info1">
              Classified Topic：
              <nuxt-link :to="`/blog/topics/${articleObj.type}`">
                {{ articleObj.type }}
              </nuxt-link>
            </div>
            <div class="info2"></div>
            <div class="info3">Update：{{ articleObj.updateTime }}</div>
            <div class="info2"></div>
            <div class="info4">{{ articleObj.reTime }} min read</div>
          </div>
        </div>
      </div>
      <div class="flex_content container-tt">
        <div class="bread-crumbs">
          <div class="bread flex_" :class="{ sticky: sticky }">
            <nuxt-link to="/">
              <div class="crumbs">Home</div>
            </nuxt-link>
            <div class="right-disabled"></div>
            <nuxt-link to="/blog">
              <div class="crumbs">Blog</div>
            </nuxt-link>
            <div class="right-disabled"></div>
            <div class="active">
              {{ articleObj.articleTitle }}
            </div>
          </div>
        </div>
        <div class="share-content-app">
          <div class="share flex_">
            <a :href="email" target="_blank">
              <img src="/static/email.svg" class="img" alt="" />
            </a>
            <a :href="pinterest" target="_blank">
              <img src="/static/pinterest.svg" class="img" alt="" />
            </a>
            <a :href="facebook" target="_blank">
              <img src="/static/facebook.svg" class="img" alt="" />
            </a>
            <a :href="twitter" target="_blank">
              <img src="/static/twitter.svg" class="img" alt="" />
            </a>
            <a :href="linkedin" target="_blank">
              <img src="/static/linkedin.svg" class="img" alt="" />
            </a>
          </div>
        </div>
        <div class="sticky-box flex_between container-tt">
          <div class="navigation-box">
            <div class="navigation" :class="{ stickyNav: sticky }">
              <div class="nav-title">Contents</div>
              <div
                :key="k"
                v-for="(item, k) in navigationList"
                @click.prevent="scrollTo(item.id)"
                class="navigation-item shou"
                :class="{ 'is-active': activeElement == item.id }"
              >
                {{ k + 1 }}. {{ item.text }}
              </div>
            </div>
          </div>
          <div class="richText">
            <div class="share-content flex_between">
              <div></div>
              <div class="share flex_">
                <a :href="email" target="_blank">
                  <img src="/static/email.svg" class="img" alt="" />
                </a>
                <a :href="pinterest" target="_blank">
                  <img src="/static/pinterest.svg" class="img" alt="" />
                </a>
                <a :href="facebook" target="_blank">
                  <img src="/static/facebook.svg" class="img" alt="" />
                </a>
                <a :href="twitter" target="_blank">
                  <img src="/static/twitter.svg" class="img" alt="" />
                </a>
                <a :href="linkedin" target="_blank">
                  <img src="/static/linkedin.svg" class="img" alt="" />
                </a>
              </div>
            </div>
            <div class="rich-img">
              <img
                :src="articleObj.imageUrl"
                class="img"
                :alt="articleObj.imageDescription"
              />
            </div>
            <div class="rich-ccontent" v-html="articleObj.content"></div>
            <div class="faqs-content">
              <h3 class="faq-tit" v-if="faqList.length != 0">FAQ</h3>
              <div class="accordion">
                <div
                  id="faq"
                  itemscope="itemscope"
                  itemtype="https://schema.org/FAQPage"
                >
                  <div
                    itemprop="mainEntity"
                    itemscope="itemscope"
                    itemtype="https://schema.org/Question"
                    class="accordion-item"
                    :key="k"
                    v-for="(item, k) in faqList"
                  >
                    <h4 itemprop="name" class="accordion-title">
                      {{ item.qaTitle }}
                    </h4>
                    <div
                      itemprop="acceptedAnswer"
                      itemscope=""
                      itemtype="https://schema.org/Answer"
                    >
                      <div
                        itemprop="text"
                        class="accordion-text f-16 c-ccc fw400"
                      >
                        {{ item.qaContent }}
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
            <div class="app-box">
              <div class="app-box__info">
                <h3 class="app-box__title f-21 fw700">
                  If you are interested in us, please visit our website or
                  download the APP to try it out
                </h3>
                <a href="/">Back to Savingtik >>></a>
              </div>
              <div class="app-link">
                <a
                  href="https://play.google.com/store/apps/details?id=tiktok.tiktokdownload.nowatermark.video.downloader"
                  target="_blank"
                >
                  <img src="/static/google-play-white.webp" alt="Google Play" />
                </a>
                <a
                  href="https://apps.apple.com/app/id6466972899"
                  target="_blank"
                >
                  <img src="/static/IOS-white.webp" alt="APP Store" />
                </a>
              </div>
            </div>
            <div class="read-more" v-if="dataList.length != 0">
              <div class="r-tit">Read More</div>
              <ul :key="k" v-for="(item, k) in dataList">
                <li class="shou">
                  <nuxt-link :to="`/blog${item.url}`">
                    <span> {{ item.articleTitle }} </span>
                  </nuxt-link>
                </li>
              </ul>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="page_content1 container-tt">
      <div class="footer">
        <!-- <pc-footer></pc-footer> -->
        <div class="bottom_nav flex_between">
          <div class="logo">
            <img src="@/static/big-logo.webp" class="img" alt="SavingTik" />
          </div>
          <div class="nav_list flex_">
            <div class="item">
              <div class="item_title">Company</div>
              <nuxt-link to="/contact">
                <div class="item_text shou">contact</div>
              </nuxt-link>
              <nuxt-link to="/blog">
                <div class="item_text shou">blog</div>
              </nuxt-link>
            </div>
            <div class="item">
              <div class="item_title shou">Legal</div>
              <nuxt-link to="/terms-of-use">
                <div class="item_text">Terms of use</div>
              </nuxt-link>
              <nuxt-link to="/privacy-policy">
                <div class="item_text">Privacy Policy</div>
              </nuxt-link>
            </div>
            <div class="item">
              <div class="item_title">Tools</div>
              <!-- <div @click="goToTools('video')" class="item_text shou">
                {{ currentObj.TikTokDownloader }}
              </div>
              <div @click="goToTools('mp3')" class="item_text shou">
                {{ currentObj.DownloadTikTokMP3 }}
              </div>
              <div @click="goToTools('story')" class="item_text shou">
                {{ currentObj.DownloadTikTokStory }}
              </div> -->
              <nuxt-link to="/save-tiktok-videos-without-posting">
                <div class="item_text shou">
                  How to save tiktok videos without posting
                </div>
              </nuxt-link>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="page_bottom flex_center">
      ©SavingTik.Com 2023 All Rights Reserved.
    </div>
    <article-content></article-content>
    <div class="app_page_bottom">
      <!-- <app-footer></app-footer> -->
      <div class="hefl flex_center">
        ©SavingTik.Com 2023 All Rights Reserved.
      </div>
      <div class="link flex_ccenter">
        <nuxt-link to="/contact">
          <div>contact</div>
        </nuxt-link>
        <nuxt-link to="/terms-of-use">
          <div class="tr">Terms of use</div>
        </nuxt-link>
        <nuxt-link to="/privacy-policy">
          <div>Privacy Policy</div>
        </nuxt-link>
        <nuxt-link to="/blog">
          <div>blog</div>
        </nuxt-link>
      </div>
    </div>
    <video src="" id="video" autoplay muted v-show="false"></video>
    <div class="dloading" v-if="dloading">
      <div class="loader"></div>
    </div>
    <van-popupapp ref="popupAppRef"></van-popupapp>
    <div class="loading-screen" v-if="loading">
      <svg viewBox="25 25 50 50">
        <circle r="20" cy="50" cx="50"></circle>
      </svg>
    </div>
  </div>
</template>
          
          <script>
import { handleClick } from "@/plugins/Firebase.js";
import language from "@/components/language.vue";
import VanPopupapp from "@/components/vanPopupapp.vue";
import PcFooter from "@/components/pcFooter.vue";
import AppFooter from "@/components/appFooter.vue";
import { mapState, mapGetters, mapMutations } from "vuex";
import dataListTools from "@/static/tools.js";
import CryptoJS from "crypto-js";
import { encryptUrl, decryptUrl } from "~/utils/encryption";

export default {
  components: { language, VanPopupapp, PcFooter, AppFooter },
  head() {
    return {
      htmlAttrs: {
        lang: "en",
      },
      bodyAttrs: {
        "data-lang": "en",
      },
      title: this.myTitle,
      script: this.myScript,
      meta: [
        {
          name: "viewport",
          content:
            "width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no",
        },
        { name: "robots", content: "index, follow" },
        { name: "revisit-after", content: "1 days" },
        {
          name: "description",
          content: this.myDescription,
        },
        {
          itemprop: "name",
          content: this.myTitle,
        },
        { name: "author", content: this.authorName },
        { property: "og:locale", content: "en" },
        { itemprop: "image", content: this.myHeadImage },
        { name: "twitter:card", content: "summary" },
        { name: "twitter:title", content: this.myTitle },
        { name: "twitter:description", content: this.myDescription },
        {
          name: "twitter:image:src",
          content: this.myHeadImage,
        },
        { name: "twitter:site", content: "SavingTik" },
        { property: "og:title", content: this.myTitle },
        { property: "og:type", content: "article" },
        { property: "og:image", content: this.myHeadImage },
        { property: "og:description", content: this.myDescription },
        { property: "og:site_name", content: this.myArticleTitle },
        { name: "google", content: "notranslate" },
      ],
      link: this.myLinks,
    };
  },
  data() {
    return {
      loading: false,
      myTitle: "",
      myDescription: "",
      myScript: [],
      authorName: "",
      myArticleTitle: "",
      myHeadImage: "",
      myLinks: [
        // Favicons
        {
          rel: "shortcut icon",
          href: "/static/logo/favicon.png",
          sizes: "512x512",
        },
        {
          rel: "apple-touch-icon",
          href: "/static/logo/favicon.png",
          sizes: "192x192",
        },
      ],
      dataList: [],
      articleObj: {},
      location: null,
      initialTop: 633, // 初始顶部的距离
      sticky: false, // 是否吸顶
      // list: dataList.listEn,
      list: [
        {
          isOpen: false,
          title: "Can I Download TikTok Videos Without Posting?",
          textContent: `Absolutely. It's entirely feasible to save TikTok videos to your gallery or camera roll without making them public. This feature is particularly useful for those who wish to review or edit their videos before sharing, or simply keep them for personal archives.`,
        },
        {
          isOpen: false,
          title: "Can I Save a TikTok Video Before Posting?",
          text: [
            `Yes, indeed! You can save your video to drafts, and then follow the steps outlined earlier to save it without posting. This method is perfect for when you're still working on your video or if you decide not to share it but want to keep a copy.`,
          ],
        },
        {
          isOpen: false,
          title: "Will Saving a Video in Private Mode Affect Its Quality?",
          text: [
            `No, saving a TikTok video in private mode does not degrade its quality. The video is saved in the same resolution and quality as it was originally created or uploaded. This ensures that you retain the best version of your creative work, whether for personal use or future editing.`,
          ],
        },
      ],
      contentTxt: "",
      dloading: false,
      showAppRight: false,
      showLanguage: false,
      Language: "en_GB",
      currentList: dataListTools.list,
      list1: [
        "en", // 英语
        "id", // 印度尼西亚语
        "vn", // 越南语
        "ms", // 马来语
        "jv", // 爪哇语
        "cs", // 捷克语
        "es", // 西班牙语
        "fr", // 法语
        "de", // 德语
        "it", // 意大利语
        "hu", // 匈牙利语
        "nl", // 荷兰语
        "pl", // 波兰语
        "pt", // 葡萄牙语
        "ro", // 罗马尼亚语
        "th", // 泰语
        "tr", // 土耳其语
        "el", // 希腊语
        "uk", // 乌克兰语
        "ru", // 俄语
        "ar", // 阿拉伯语
        "ko", // 韩语
        "ja", // 日语
      ],
      faqList: [],
      navigationList: [],
      activeElement: null,
    };
  },
  async asyncData({ env, route, error, req }) {
    let location;
    // 检查是否在服务器上下文中
    if (process.server && req) {
      location = req.headers.referer;
    }

    // 其余变量初始化
    let authorObj = {};
    let authorList = [];
    let dataList = [];
    let articleObj = {};

    // ...其余数据获取逻辑，例如获取作者详情和文章列表

    // 获取文章详细信息的逻辑
    const articleId = route.path.replace("/blog", ""); // 使用 route.params 获取动态路由参数
    const articleDetailResult = encryptUrl(
      JSON.stringify({
        id: articleId,
        packageName: "WebTt",
      }),
      env
    );

    try {
      // ...组合所有 Promise.all 中的请求
      // 获取文章详细信息的请求
      const articleDetailResponse = await fetch(
        "https://savingtik.com/js/a/api/cms/web/articleDetailById",
        {
          method: "POST",
          body: JSON.stringify({ condition: articleDetailResult }),
          headers: {
            "Content-Type": "application/json",
          },
        }
      );

      if (!articleDetailResponse.ok) {
        throw new Error("Error fetching article details");
      }

      const articleDetailData = await articleDetailResponse.json();

      // 判断并处理文章详情数据
      if (articleDetailData.code !== 200) {
        error({
          statusCode: 404,
          message: "Post not found",
        });
        return { location, authorObj, authorList, dataList, articleObj }; // 提前返回以中断函数执行
      }

      const decryptedData = await decryptUrl(articleDetailData.data, env);
      const res = JSON.parse(decryptedData);
      articleObj = { ...res, location }; // 此处我们结合文章数据和地址信息
    } catch (error) {
      console.error("asyncData error:", error);
      // 如果需要错误处理，可以使用 error 函数
      error({ statusCode: 500, message: "Internal Server Error" });
    }

    // 返回一个对象，该对象将合并到组件实例的数据中
    return { location, authorObj, authorList, dataList, articleObj };
  },

  mounted() {
    window.addEventListener("scroll", this.checkStickiness);
    window.addEventListener("scroll", this.findActiveElement);
    this.checkStickiness();
    this.getFaqList(this.articleObj.id);
    this.getCateArticleList(this.articleObj.typeId);
    this.updateTitleAndDescription(
      this.articleObj.pageTitle,
      this.articleObj.pageDescription,
      this.articleObj.fjson,
      this.articleObj.author,
      this.articleObj.articleTitle,
      this.articleObj.imageUrl
    );
    this.getform()
    // this.getArticleDtl();
  },
  beforeDestroy() {
    window.removeEventListener("scroll", this.checkStickiness);
    window.removeEventListener("scroll", this.findActiveElement);
  },
  computed: {
    ...mapGetters(["language"]),
    currentObj() {
      return this.currentList[this.current];
    },
    current() {
      return this.list1.findIndex((x) => x == this.language);
    },
    email() {
      return (
        "mailto:?subject=" +
        this.articleObj.articleTitle +
        "&body=" +
        encodeURIComponent(this.location)
      );
    },
    facebook() {
      return (
        "https://www.facebook.com/sharer.php?u=" +
        encodeURIComponent(this.location)
      );
    },
    twitter() {
      return (
        "https://twitter.com/intent/tweet?url=" +
        encodeURIComponent(this.location) +
        "&text=" +
        this.articleObj.articleDescription
      );
    },
    pinterest() {
      return (
        "http://pinterest.com/pin/create/button/?url=" +
        encodeURIComponent(this.location) +
        "&media=" +
        this.articleObj.imageUrl +
        "&description=" +
        this.articleObj.articleDescription
      );
    },
    linkedin() {
      return (
        "https://www.linkedin.com/shareArticle?mini=true&url=" +
        encodeURIComponent(this.location) +
        "&title=" +
        this.articleObj.articleTitle +
        "&summary=" +
        this.articleObj.articleDescription
      );
    },
  },
  methods: {
    getform(){
      let that = this
       // 先解析HTML字符串
       var parser = new DOMParser();
            var doc = parser.parseFromString(this.articleObj.content, "text/html");
            // 获取所有h1和h2元素的数组
            var headings = Array.from(
              doc.querySelectorAll("h1, h2,h3,h4,h5,h6")
            );
            var ps = Array.from(doc.querySelectorAll("p"));
            ps.forEach((x) => {
              x.style.margin = "10px 0";
            });
            // 遍历所有的h1和h2
            let idCounter = 1;
            let toc = []; // 用于存放提取的文本内容和id，用于生成侧边导航条目
            var images = doc.querySelectorAll("img");

            // 遍历图片并修改样式
            images.forEach((img) => {
              img.style.maxWidth = "100%";
              img.style.height = "auto";
              img.style.margin = "10px 0";
              img.style.marginLeft = "auto";
              img.style.marginRight = "auto";
            });
            headings.forEach((heading) => {
              // 添加唯一id
              heading.id = "heading-id" + idCounter++;
              // 提取文本内容
              let textContent = heading.textContent;
              switch (heading.tagName) {
                case "H1":
                  heading.style.margin = "40px 0";
                  break;
                case "H2":
                  heading.style.margin = "24px 0px";
                  break;
                case "H3":
                  heading.style.margin = "18px 0";
                  break;
                case "H4":
                  heading.style.margin = "10px 0";
                  break;
                case "H5":
                  heading.style.margin = "10px 0";
                  break;
                default:
                  break;
              }
              // 存储到toc数组中，和它的id一起
              toc.push({
                id: heading.id,
                text: textContent,
              });
            });
            // 打印toc的内容
            this.navigationList = toc;
            this.articleObj.content = doc.documentElement.outerHTML;
    },
    findActiveElement() {
      let scrollY = window.pageYOffset;
      let nearestElement = null;
      let nearestDistance = Infinity;

      this.navigationList.forEach((item) => {
        let element = document.getElementById(item.id);
        if (element) {
          let distance = Math.abs(element.getBoundingClientRect().top);

          if (distance < nearestDistance) {
            nearestDistance = distance;
            nearestElement = item.id;
          }
        }
      });

      if (nearestElement !== this.activeElement) {
        this.activeElement = nearestElement;
      }
    },
    getCateArticleList(typeid) {
      let that = this;
      let result = this.encryptUrl(
        JSON.stringify({
          pageNo: 1,
          pageSize: 9999,
          typeId: typeid,
          packageName: "WebTt",
        })
      );
      fetch("https://savingtik.com/js/a/api/cms/web/listData", {
        method: "POST",
        body: JSON.stringify({
          condition: result,
        }),
        headers: {
          "Content-Type": "application/json",
        },
      }).then((response) => {
        response.json().then(async (data) => {
          data = await this.decryptUrl(data.data);
          let res = JSON.parse(data);
          if (res.list.length == 0) return;
          that.dataList = res.list.filter(
            (item) => item.id != that.articleObj.id
          );
        });
      });
    },
    encryptUrl(input) {
      let CIPHER_ALGORITHM = "DES-CBC";
      let IV_SIZE = 8;
      let KEY_PWD = process.env.DES_CMS_KEY;
      try {
        const keyBytes = CryptoJS.enc.Utf8.parse(KEY_PWD);
        const inputBytes = CryptoJS.enc.Utf8.parse(input);
        const ivBytes = CryptoJS.lib.WordArray.random(IV_SIZE);
        const encrypted = CryptoJS.DES.encrypt(inputBytes, keyBytes, {
          iv: ivBytes,
          mode: CryptoJS.mode.CBC,
          padding: CryptoJS.pad.Pkcs7,
        });
        const ciphertext = ivBytes.concat(encrypted.ciphertext);
        return ciphertext.toString();
      } catch (error) {
        console.error(error);
        return null;
      }
    },
    decryptUrl(cipherText) {
      let CIPHER_ALGORITHM = "DES-CBC";
      let IV_SIZE = 8;
      let KEY_PWD = process.env.DES_CMS_KEY;
      try {
        let keyBytes = CryptoJS.enc.Utf8.parse(
          KEY_PWD.padEnd(CIPHER_ALGORITHM === "DES-CBC" ? 8 : 16)
        );
        let ivBytes = { iv: CryptoJS.enc.Hex.parse(process.env.DES_CMS_IV) }; // 如果使用CBC模式，需要一个初始化向量iv，这里是空向量
        let decrypted = CryptoJS.DES.decrypt(
          { ciphertext: CryptoJS.enc.Hex.parse(cipherText) },
          keyBytes,
          ivBytes
        );
        return decrypted.toString(CryptoJS.enc.Utf8);
      } catch (e) {
        console.error(e);
        return null;
      }
    },
    StorageAuthorId() {
      localStorage.setItem("AuthorId", this.articleObj.authorId);
    },
    getFaqList(id) {
      let that = this;
      let result = this.encryptUrl(
        JSON.stringify({
          articleId: id,
          packageName: "WebTt",
        })
      );
      fetch("https://savingtik.com/js/a/api/cms/qa/qaByArticleId", {
        method: "POST",
        body: JSON.stringify({
          condition: result,
        }),
        headers: {
          "Content-Type": "application/json",
        },
      }).then((response) => {
        response.json().then(async (data) => {
          if (data.code == 200) {
            data = await this.decryptUrl(data.data);
            let res = JSON.parse(data);
            that.faqList = res;
          } else {
            that.faqList = [];
          }
        });
      });
    },
    scrollTo(id) {
      const element = document.getElementById(id);
      if (element) {
        const rect = element.getBoundingClientRect();
        window.scrollTo({
          top: rect.top + window.scrollY - 100,
          behavior: "smooth",
        });
      }
    },
    getArticleDtl() {
      this.loading = true;
      let id = this.$route.path.replace("/blog", "");
      let that = this;
      let result = this.encryptUrl(
        JSON.stringify({
          id: id,
          packageName: "WebTt",
        })
      );
      fetch("https://savingtik.com/js/a/api/cms/web/articleDetailById", {
        method: "POST",
        body: JSON.stringify({
          condition: result,
        }),
        headers: {
          "Content-Type": "application/json",
        },
      }).then((response) => {
        response.json().then(async (data) => {
          this.loading = false;

          if (data.code != 200) {
            this.$nuxt.error({
              statusCode: 404,
              message: "Post not found",
            });
          } else {
            data = await this.decryptUrl(data.data);
            let res = JSON.parse(data);
            this.getFaqList(res.id);
            let date = new Date(res.updateTime);
            let month = date.toLocaleString("en-US", { month: "short" });
            let day = date.getDate();
            let year = date.getFullYear();
            res.updateTime = month + " " + day + ", " + year;
            that.articleObj = res;
            // navigationList
            that.getCateArticleList(res.typeId);
            that.updateTitleAndDescription(
              res.pageTitle,
              res.pageDescription,
              res.fjson,
              res.author,
              res.articleTitle,
              res.imageUrl
            );

            // 先解析HTML字符串
            var parser = new DOMParser();
            var doc = parser.parseFromString(res.content, "text/html");
            // 获取所有h1和h2元素的数组
            var headings = Array.from(
              doc.querySelectorAll("h1, h2,h3,h4,h5,h6")
            );
            var ps = Array.from(doc.querySelectorAll("p"));
            ps.forEach((x) => {
              x.style.margin = "10px 0";
            });
            // 遍历所有的h1和h2
            let idCounter = 1;
            let toc = []; // 用于存放提取的文本内容和id，用于生成侧边导航条目
            var images = doc.querySelectorAll("img");

            // 遍历图片并修改样式
            images.forEach((img) => {
              img.style.maxWidth = "100%";
              img.style.height = "auto";
              img.style.margin = "10px 0";
              img.style.marginLeft = "auto";
              img.style.marginRight = "auto";
            });
            headings.forEach((heading) => {
              // 添加唯一id
              heading.id = "heading-id" + idCounter++;
              // 提取文本内容
              let textContent = heading.textContent;
              switch (heading.tagName) {
                case "H1":
                  heading.style.margin = "40px 0";
                  break;
                case "H2":
                  heading.style.margin = "24px 0px";
                  break;
                case "H3":
                  heading.style.margin = "18px 0";
                  break;
                case "H4":
                  heading.style.margin = "10px 0";
                  break;
                case "H5":
                  heading.style.margin = "10px 0";
                  break;
                default:
                  break;
              }
              // 存储到toc数组中，和它的id一起
              toc.push({
                id: heading.id,
                text: textContent,
              });
            });
            // 打印toc的内容
            that.navigationList = toc;
            that.articleObj.content = doc.documentElement.outerHTML;
            // 导航块应当可以使用toc数组来构建。在点击对应的导航项时，滚动到对应ID的位置即可。
          }
        });
      });
    },
    updateTitleAndDescription(
      newTitle,
      newDescription,
      newScript,
      authorName,
      myArticleTitle,
      myHeadImage
    ) {
      this.authorName = authorName;
      this.myTitle = newTitle;
      this.myDescription = newDescription;
      this.myArticleTitle = myArticleTitle;
      this.myHeadImage = myHeadImage;
      if (newScript) {
        let script = eval("(" + newScript + ")");
        this.myScript.push(script);
      }
      this.myLinks.push({
        rel: "canonical",
        href: "https://savingtik.com" + this.$route.path,
      });
    },
    checkStickiness() {
      if (window.scrollY >= this.initialTop) {
        this.sticky = true;
      } else {
        this.sticky = false;
      }
    },
    getPageNo(newPageNo) {
      this.pageNo = newPageNo;
      // 你也可以在这里加入更多的逻辑
      // 例如，你可能希望用新的页面编号来发送一个新的API请求
    },
    showAppRightHandel() {
      this.$refs.popupAppRef.open();
    },
    showLanguageHandel() {
      this.$refs.languageRef.close();
    },
    goToApp(type) {
      let url = "";
      switch (type) {
        case "video":
          url = "";
          break;
        case "mp3":
          url = "/download-tiktok-mp3";
          break;
        default:
          url = "/download-tiktok-story";
      }
      if (this.language !== "en") {
        url = `/${this.language}${url}`;
      } else if (this.language == "en" && type == "video") {
        url = `/`;
      }
      this.$router.push(url);
      // 切换页面 action_page_switch
      handleClick("action_page_switch", {
        site: type,
        from: "top",
      });
    },
    goToTop(type) {
      // 切换页面 action_page_switch
      handleClick("action_page_switch", {
        site: type,
        from: "top",
      });
    },
    goToTools(type) {
      // 切换页面 action_page_switch
      handleClick("action_page_switch", {
        site: type,
        from: "tools",
      });
    },

    changeLanguage() {
      if (this.$i18n.locale == "en") {
        this.$i18n.setLocale("zh");
      } else {
        this.$i18n.setLocale("en");
      }
    },
    changeFaqItemOpen(item, k) {
      item.isOpen = !item.isOpen;
    },
  },
};
</script>
<style lang="scss" scoped>
.loading-screen {
  background: rgba(255, 255, 255, 0.7);
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

svg {
  width: 3.25em;
  transform-origin: center;
  animation: rotate4 2s linear infinite;
}

circle {
  fill: none;
  stroke: hsl(214, 97%, 59%);
  stroke-width: 2;
  stroke-dasharray: 1, 200;
  stroke-dashoffset: 0;
  stroke-linecap: round;
  animation: dash4 1.5s ease-in-out infinite;
}

@keyframes rotate4 {
  100% {
    transform: rotate(360deg);
  }
}

@keyframes dash4 {
  0% {
    stroke-dasharray: 1, 200;
    stroke-dashoffset: 0;
  }

  50% {
    stroke-dasharray: 90, 200;
    stroke-dashoffset: -35px;
  }

  100% {
    stroke-dashoffset: -125px;
  }
}

@media (min-width: 992px) {
  .container-tt {
    max-width: 960px;
    margin-left: auto;
    margin-right: auto;
    .richText {
      max-width: calc(960px - 270px);
    }
  }

  .page_content1 .footer .bottom_nav .nav_list {
    align-items: flex-start;
    .item {
      margin-left: 100px;
      width: 160px;
      .item_title {
        margin-bottom: 20px;
        font-size: 18px;
        font-family: Poppins-Bold, Poppins;
        font-weight: bold;
      }
      .item_text {
        margin-bottom: 20px;
        font-size: 14px;
        font-family: Poppins-Regular, Poppins;
        font-weight: 400;
        color: rgba(29, 33, 44, 0.5);
      }
    }
  }
}

@media (min-width: 1200px) {
  .container-tt {
    max-width: 1140px;
    margin-left: auto;
    margin-right: auto;
    .richText {
      max-width: calc(1140px - 270px);
    }
  }
  .nav_list {
    align-items: flex-start;
    .item {
      margin-left: 140px !important;
      width: 200px !important;
      .item_title {
        margin-bottom: 20px;
        font-size: 18px;
        font-family: Poppins-Bold, Poppins;
        font-weight: bold;
      }
      .item_text {
        margin-bottom: 20px;
        font-size: 14px;
        font-family: Poppins-Regular, Poppins;
        font-weight: 400;
        color: rgba(29, 33, 44, 0.5);
      }
    }
  }
}
::-webkit-scrollbar {
  width: 0.5em;
  background-color: transparent;
}

::-webkit-scrollbar-track {
  background-color: transparent;
}

::-webkit-scrollbar-thumb {
  background-color: #fff;
  border-radius: 0.5em;
}

::-webkit-scrollbar-thumb:hover {
  background-color: #fff;
}
.container {
  background-color: #fff !important;
  color: rgba(29, 33, 44, 1);
}
.is-active {
  color: #fff !important; // 换成你需要的颜色
  background-color: rgba(6, 74, 218, 1);
}
.sticky {
  position: fixed !important;
  top: 0px;
}
.stickyNav {
  position: fixed !important;
  top: 85px;
  width: 270px;
}
.container {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
button {
  background: none;
  color: inherit;
  border: none;
  padding: 0;
  font: inherit;
  cursor: pointer;
  outline: inherit;
}

@media (min-width: 1024px) {
  .page_content1 {
    z-index: 100;
    .footer {
      /* // position: relative; */
      margin-top: 300px;
      .bottom_nav {
        align-items: flex-start;
        .logo {
          transform: translate(-10px, -27px);
          width: 132px;
          height: 171px;
        }
      }
    }
  }
  .share-content-app {
    display: none;
  }
  .page_content {
    z-index: 100;
    width: 100%;

    header {
      /* // position: relative; */
      padding: 14px 0;
      z-index: 999;
      .headLogo {
        width: 34px;
        height: 34px;
        .projectName {
          font-size: 21px;
          font-family: Inter-Extra Bold Italic, Inter;
          font-weight: 800;
          font-style: italic;
          margin-left: 14px;
        }
      }
      .drawer {
        display: none;
      }
      .headTabs {
        .tItem {
          position: relative;
          text-align: right;
          height: 58px;
          font-size: 14px;
          font-family: Poppins-Light, Poppins;
          color: rgba(29, 33, 44, 0.5);
          line-height: 58px;
          margin-left: 70px;

          .expand {
            position: absolute;
            top: 0;
            right: -20px;
            width: 10px;
            height: 8px;
            margin-left: 4px;
          }
          .Language_box {
            position: absolute;
            left: 100px;
            bottom: -200px;
            z-index: 9999;
            width: 162px;
            height: 177px;
            background: rgba(43, 67, 89, 0.15);
            border-radius: 12px;
            overflow-y: scroll;
            padding: 0 14px;
            .item {
              padding: 14px 0;
              border-bottom: 1px solid rgba(125, 125, 125, 0.1);
              font-size: 14px;
              font-family: Poppins-Regular, Poppins;
              font-weight: 400;
              color: rgba(255, 255, 255, 0.5);
              text-align: center;
              line-height: 1;
              .dian {
                width: 4px;
                height: 4px;
                border-radius: 50%;
                background-color: rgba(0, 255, 247, 1);
                margin-right: 10px;
              }
            }
            .changeItemColor {
              font-size: 14px;
              font-family: Poppins-Regular, Poppins;
              font-weight: 400;
            }
            .item:last-child {
              border: 0;
            }
          }
        }
        .bor {
          border-bottom: 1px solid rgba(255, 255, 255, 0.5);
        }
        .tItemFFF {
        }
        .tItemBlod {
          font-weight: 700;
          /* // font-family: Poppins-Bold, Poppins; */
        }
      }
    }
  }
  .page_bottom {
    margin-top: 30px;
    padding: 40px 0;
    border-top: 2px solid rgba(217, 217, 217, 0.2);
    font-size: 14px;
    font-family: Poppins-Regular, Poppins;
    color: rgba(29, 33, 44, 0.5);
  }
  .app_page_bottom {
    display: none;
  }
  .blog-content {
    flex: 1;
    .background {
      background-color: rgba(6, 74, 218, 1);
      padding: 50px 0;
      color: #fff;
      .content {
        margin-left: auto;
        margin-right: auto;
        padding: 0 40px;
        .cateImg {
          overflow: hidden;
          width: 120px;
          height: 120px;
          border-radius: 4px;
        }
        .alt-title {
          margin: 36px 0;
          font-size: 56px;
          font-weight: 700;
          text-align: center;
        }
        .uname {
          font-size: 18px;
          .name {
            text-decoration: underline;
            margin-left: 4px;
          }
        }
        .info-box {
          margin-top: 20px;
          font-size: 18px;
          .info2 {
            width: 5px;
            height: 5px;
            margin: 0 14px;
          }
        }
      }
    }
    .flex_content {
      position: initial;
      align-items: flex-start;
      .bread-crumbs {
        margin-left: auto;
        margin-right: auto;
        .bread {
          padding: 30px 0;
          background-color: #fff;
          width: 100%;
        }
        .crumbs {
          color: rgba(29, 33, 44, 0.5);
          font-size: 18px;
        }
        .right-disabled {
          margin: 0 10px;
          width: 24px !important;
          height: 24px !important;
          background-image: url("@/static/next-disabled.webp");
          background-size: 24px 24px;
          background-repeat: no-repeat;
        }
        .active {
          font-size: 18px;
        }
      }
      .sticky-box {
        width: 100%;
        z-index: 9999;
        align-items: flex-start;
        .navigation-box {
          width: 270px;
          .nav-title {
            font-size: 21px;
            font-weight: 700;
            padding: 20px;
            padding-top: 0;
            padding-left: 14px;
          }
          .navigation {
            height: auto;
            border-radius: 12px;
            padding: 20px 0;
            background-color: rgba(228, 233, 239, 1);
            z-index: 99999;
            .navigation-item {
              color: rgba(29, 33, 44, 0.5);
              font-size: 16px;
              padding: 14px 10px;
              line-height: 20px;
            }
          }
        }
        .richText {
          flex: 1;
          padding-left: 50px;
          .share-content {
            .share {
              a {
                .img {
                  width: 24px;
                  height: 24px;
                  margin-left: 14px;
                }
              }
            }
          }
          .rich-img {
            overflow: hidden;
            width: 100%;
            height: 449px;
            border-radius: 12px;
            margin-top: 20px;
            margin-bottom: 30px;
            .img {
              width: 100%;
              height: 100%;
              object-fit: cover;
            }
          }
          .faqs-content {
            margin-top: 20px;
            .faq-tit {
              font-size: 32px;
              font-weight: 700;
            }
            .accordion {
              margin-top: 30px;
              .accordion-item {
                margin-bottom: 40px;
                .accordion-title {
                  color: rgba(6, 74, 218, 1);
                  font-size: 18px;
                  font-weight: 700;
                }
                .accordion-text {
                  margin-top: 10px;
                  font-size: 16px;
                  color: rgba(29, 33, 44, 0.5);
                  font-style: italic;
                }
              }
            }
          }
          .app-box {
            width: 100%;
            display: flex;
            flex-direction: row;
            justify-content: space-between;
            padding: 30px 24px;
            gap: 64px;
            margin-top: 24px;
            border-radius: 12px;
            background: rgba(6, 74, 218, 1);
            color: #fff;
            .app-box__info {
              text-align: left;
              font-size: 18px;
              h3 {
                margin-bottom: 20px;
              }
              a {
                color: #3ec6ff;
              }
            }
            .app-link {
              display: flex;
              align-items: center;
              gap: 16px;
              a {
                img {
                  width: 154px;
                  height: 48px;
                }
              }
            }
          }
          .read-more {
            margin-top: 30px;
            .r-tit {
              font-weight: 700;
              font-size: 32px;
              margin-bottom: 20px;
            }
            ul {
              list-style-type: none !important;
              list-style: none !important;
              li {
                margin-bottom: 8px;
                list-style: none !important;
                font-size: 16px;
                span {
                  text-decoration: underline;
                  color: rgba(6, 74, 218, 1);
                }
              }
            }
            ul li::before {
              content: "•";
              font-size: 20px;
              color: rgba(6, 74, 218, 1);
              margin-right: 10px;
            }
          }
        }
      }
    }
  }
}
@media (max-width: 1023px) {
  .sticky {
    position: relative !important;
  }
  .stickyNav {
    position: static !important;
    width: 100%;
  }
  /* 当设备屏幕宽度小于等于1023像素时，应用其中定义的样式。 */
  .blog-content {
    flex: 1;
    .background {
      background-color: rgba(6, 74, 218, 1);
      padding: 30px 0;
      color: #fff;
      .content {
        padding: 0 40px;
        .cateImg {
          overflow: hidden;
          width: 100px;
          height: 100px;
          border-radius: 4px;
        }
        .alt-title {
          margin: 16px 0;
          font-size: 30px;
          font-weight: 700;
          text-align: center;
        }
        .uname {
          font-size: 16px;
          .name {
            text-decoration: underline;
            margin-left: 4px;
          }
        }
        .info-box {
          margin-top: 20px;
          font-size: 14px;
          display: flex;
          flex-direction: column;
          .info2 {
            margin: 2px 0;
          }
        }
      }
    }
    .flex_content {
      position: initial;
      align-items: flex-start;
      padding: 0 24px;
      .bread-crumbs {
        .bread {
          flex-wrap: wrap;
          padding: 14px 0;
          background-color: #fff;
          width: 100%;
        }
        .crumbs {
          color: rgba(29, 33, 44, 0.5);
          font-size: 14px;
          margin-bottom: 10px;
        }
        .right-disabled {
          margin: 0 10px;
          width: 24px !important;
          height: 24px !important;
          background-image: url("@/static/next-disabled.webp");
          background-size: 24px 24px;
          background-repeat: no-repeat;
          margin-bottom: 10px;
        }
        .active {
          font-size: 14px;
        }
      }
      .share-content-app {
        margin-bottom: 16px;
        .share {
          a {
            .img {
              width: 26px;
              height: 26px;
              margin-right: 20px;
            }
          }
        }
      }
      .sticky-box {
        display: flex !important;
        flex-direction: column !important;
        .navigation-box {
          width: 100%;
          .nav-title {
            font-weight: 700;
            font-size: 16px;
            padding: 10px;
          }
          .navigation {
            height: auto;
            border-radius: 12px;
            background-color: rgba(228, 233, 239, 1);
            .navigation-item {
              padding: 10px 14px;
              text-decoration: underline;
              color: rgba(29, 33, 44, 0.5);
            }
          }
        }
        .richText {
          width: 100%;
          max-width: 100%;
          .share-content {
            display: none !important;
            .share {
              a {
                .img {
                  width: 24px;
                  height: 24px;
                  margin-left: 14px;
                }
              }
            }
          }
          .rich-img {
            overflow: hidden;
            width: 100%;
            height: 200px;
            border-radius: 12px;
            margin-top: 20px;
            margin-bottom: 30px;
            .img {
              width: 100%;
              height: 100%;
              object-fit: cover;
            }
          }
          .faqs-content {
            margin-top: 20px;
            .faq-tit {
              font-size: 24px;
              text-align: center;
              font-weight: 700;
              span {
                display: none;
              }
            }
            .accordion {
              margin-top: 30px;
              .accordion-item {
                margin-bottom: 24px;
                .accordion-title {
                  color: rgba(6, 74, 218, 1);
                  font-size: 18px;
                  font-weight: 700;
                }
                .accordion-text {
                  margin-top: 10px;
                  font-size: 16px;
                  color: rgba(29, 33, 44, 0.5);
                  font-style: italic;
                }
              }
            }
          }
          .app-box {
            width: 100%;
            padding: 20px 24px;
            margin-top: 24px;
            border-radius: 12px;
            background: rgba(6, 74, 218, 1);
            text-align: center;
            color: #fff;

            .app-box__info {
              text-align: center;
              h3 {
                font-size: 18px;
                margin-bottom: 20px;
              }
              a {
                color: #3ec6ff;
                font-size: 16px;
              }
            }
            .app-link {
              width: 100%;
              margin-top: 20px;
              display: flex;
              align-items: center;
              gap: 16px;
              a {
                width: 49%;

                img {
                  width: 100%;
                  height: 48px;
                }
              }
            }
          }
          .read-more {
            margin-top: 30px;
            .r-tit {
              font-weight: 700;
              font-size: 24px;
              margin-bottom: 20px;
            }
            ul {
              list-style-type: none !important;
              list-style: none !important;
              li {
                margin-bottom: 8px;
                list-style: none !important;
                font-size: 16px;
                span {
                  text-decoration: underline;
                  color: rgba(6, 74, 218, 1);
                }
              }
            }
            ul li::before {
              content: "•";
              font-size: 16px;
              color: rgba(6, 74, 218, 1);
            }
          }
        }
      }
    }
  }
  .page_content1 {
    display: none;
  }
  .page_content {
    padding: 0 24px;
    z-index: 100;
    width: 100%;

    header {
      /* // position: relative; */
      padding: 14px;
      z-index: 999;
      .headLogo {
        transform: translateX(-14px);
        width: 19px;
        height: 19px;
        .projectName {
          font-size: 12px;
          font-family: Inter-Extra Bold Italic, Inter;
          font-weight: 800;
          font-style: italic;
          margin-left: 12px;
        }
      }
      .drawer {
        display: block;
        width: 26px;
        height: 26px;
        transform: translateX(14px);
      }
      .headTabs {
        display: none;
        .tItem {
          position: relative;
          width: 220px;
          text-align: right;
          height: 38px;
          font-size: 14px;
          font-family: Poppins-Light, Poppins;
          color: rgba(255, 255, 255, 0.5);
          line-height: 38px;
          .bor {
            position: absolute;
            bottom: -18px;
            left: 82px;
            width: 142px;
            height: 1px;
            background: rgba(255, 255, 255, 0.5);
          }
          .expand {
            position: absolute;
            top: 0;
            right: -20px;
            width: 10px;
            height: 8px;
            margin-left: 4px;
          }
          .Language_box {
            position: absolute;
            left: 100px;
            bottom: -200px;
            z-index: 9999;
            width: 162px;
            height: 177px;
            background: rgba(43, 67, 89, 0.15);
            border-radius: 12px;
            overflow-y: scroll;
            padding: 0 14px;
            .item {
              padding: 14px 0;
              border-bottom: 1px solid rgba(125, 125, 125, 0.1);
              font-size: 14px;
              font-family: Poppins-Regular, Poppins;
              font-weight: 400;
              color: rgba(255, 255, 255, 0.5);
              text-align: center;
              line-height: 1;
              .dian {
                width: 4px;
                height: 4px;
                border-radius: 50%;
                background-color: rgba(0, 255, 247, 1);
                margin-right: 10px;
              }
            }
            .changeItemColor {
              font-size: 14px;
              font-family: Poppins-Regular, Poppins;
              font-weight: 400;
            }
            .item:last-child {
              border: 0;
            }
          }
        }
        .tItemFFF {
        }
        .tItemBlod {
          font-weight: 700;
          /* // font-family: Poppins-Bold, Poppins; */
        }
      }
    }
    .blog-content {
    }
    .footer {
      display: none;
      margin-top: 300px;
      .bottom_nav {
        align-items: flex-start;
        .logo {
          transform: translate(-60px, -77px);
          width: 182px;
          height: 182px;
        }
        .nav_list {
          align-items: flex-start;
          .item {
            margin-left: 140px;
            .item_title {
              margin-bottom: 20px;
              font-size: 21px;
              font-family: Poppins-Bold, Poppins;
              font-weight: bold;
            }
            .item_text {
              margin-bottom: 20px;
              font-size: 16px;
              font-family: Poppins-Regular, Poppins;
              font-weight: 400;
              color: rgba(255, 255, 255, 0.5);
            }
          }
        }
      }
    }
  }
  .page_bottom {
    display: none;
    margin-top: 100px;
    padding: 40px 0;
    border-top: 2px solid rgba(217, 217, 217, 0.1);
    font-size: 14px;
    font-family: Poppins-Regular, Poppins;
    color: rgba(255, 255, 255, 0.2);
  }
  .app_page_bottom {
    margin-top: 60px;
    padding: 14px 40px;
    padding-bottom: 20px;
    border-top: 1px solid rgba(228, 233, 239, 1);
    font-family: Poppins-Regular, Poppins;
    color: rgba(29, 33, 44, 0.5);
  }
}
.hefl {
  color: rgba(29, 33, 44, 0.7);
  font-size: 10px;
  margin-bottom: 12px;
}
.link {
  position: relative;
  font-size: 12px;
  div {
    height: 50px;
    line-height: 50px;
  }
}
@media (min-width: 992px) {
  .rich-img {
    height: 300px !important;
  }
}

@media (min-width: 1200px) {
  .rich-img {
    height: 370px !important;
  }
}
</style>